package cn.net.yugu.doraemon.scheduler;

import java.util.List;

import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.executor.XxlJobExecutor;
import com.xxl.job.core.handler.IJobHandler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 抽象的执行器
 *
 * @author xiangzr
 * @version 2023/8/31 17:08:17
 */
@Slf4j
@RequiredArgsConstructor
public class XxlJobJobHandlerRegistry {

    private final List<JobHandler> jobHandlers;

    public void init() throws Exception {
        if (jobHandlers == null || jobHandlers.isEmpty()) {
            log.info("当前应用不存在定时 JobHandler");
            return;
        }
        log.info("register JobHandler start total {}", jobHandlers.size());
        jobHandlers.forEach(handler -> {
            final String jobName = handler.getClass().getCanonicalName();
            log.info("register JobHandler {}", jobName);
            XxlJobExecutor.registJobHandler(jobName, new IJobHandler() {
                @Override
                public void execute() throws Exception {
                    int shardIndex = XxlJobHelper.getShardIndex();
                    int shardTotal = XxlJobHelper.getShardTotal();
                    final String jobParam = XxlJobHelper.getJobParam();
                    final long start = System.currentTimeMillis();
                    log.info("job execute started. jobName {} shardIndex {} shardTotal {} jobParam {}", jobName, shardIndex, shardTotal, jobParam);
                    try {
                        handler.execute(shardIndex, shardTotal, jobParam);
                        log.info("job execute completed. jobName {} shardIndex {} shardTotal {} jobParam {} cost {} ms",
                                 jobName, shardIndex, shardTotal, jobParam, System.currentTimeMillis() - start);
                        XxlJobHelper.handleSuccess("Execute Success.");
                    } catch (Throwable e) {
                        if (e instanceof InterruptedException) {
                            log.warn("job execute Interrupted. jobName {} shardIndex {} shardTotal {} jobParam {}",
                                     jobName, shardIndex, shardTotal, jobParam);
                            throw e;
                        }
                        log.error("job execute fail. jobName {} shardIndex {} shardTotal {} jobParam {}", jobName, shardIndex, shardTotal, jobParam, e);
                        XxlJobHelper.handleFail("job execute fail:" + e.getMessage());
                    }
                }

                @Override
                public void init() throws Exception {
                    handler.init();
                }

                @Override
                public void destroy() throws Exception {
                    handler.destroy();
                }
            });
        });
        log.info("register JobHandler completed.");
    }
}
